package top.bulk.file.service.impl;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import top.bulk.file.service.FileUploadService;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 实现
 *
 * @author 散装java
 * @date 2022-08-19
 */
@Service
public class FileUploadServiceImpl implements FileUploadService {
    private static final String FILE_PATH = "d:/tmp/img/";
    private static final Map<String, Image> IMG_CACHE = new HashMap<>();

    @SneakyThrows
    @Override
    public void uploadAndCut(MultipartFile file, String uuid) {
        InputStream inputStream = file.getInputStream();
        BufferedImage image = ImgUtil.read(inputStream);
        int width = image.getWidth();
        int height = image.getHeight();
        // +1 是为了向上取整。不然多月的长度会单独形成一个图片
        int cutWidth = width / 3 + 1;
        int cutHeight = height / 3 + 1;
        ImgUtil.slice(image, FileUtil.file(FILE_PATH + uuid), cutWidth, cutHeight);
//        this.slice(image, cutWidth, cutHeight, uuid);
    }

    @Override
    public List<String> getImgList(String uuid) {
        File file = FileUtil.file(FILE_PATH + uuid);
        String[] list = file.list();
        assert list != null;
        return Arrays.asList(list);
    }

    /**
     * 基于 hutool 切图工具改造而来，将结果存入缓存，方便进行前端取图操作
     *
     * @param srcImage   目标图片
     * @param destWidth  宽度
     * @param destHeight 高度
     * @param uuid       uuid 标识id
     */
    private void slice(Image srcImage, int destWidth, int destHeight, String uuid) {
        // 切片宽度
        if (destWidth <= 0) {
            destWidth = 200;
        }
        // 切片高度
        if (destHeight <= 0) {
            destHeight = 150;
        }
        // 源图宽度
        int srcWidth = srcImage.getWidth(null);
        // 源图高度
        int srcHeight = srcImage.getHeight(null);

        if (srcWidth < destWidth) {
            destWidth = srcWidth;
        }
        if (srcHeight < destHeight) {
            destHeight = srcHeight;
        }

        int cols; // 切片横向数量
        int rows; // 切片纵向数量
        // 计算切片的横向和纵向数量
        if (srcWidth % destWidth == 0) {
            cols = srcWidth / destWidth;
        } else {
            cols = (int) Math.floor((double) srcWidth / destWidth) + 1;
        }
        if (srcHeight % destHeight == 0) {
            rows = srcHeight / destHeight;
        } else {
            rows = (int) Math.floor((double) srcHeight / destHeight) + 1;
        }
        // 循环建立切片
        Image tag;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // 四个参数分别为图像起点坐标和宽高
                // 即: CropImageFilter(int x,int y,int width,int height)
                tag = ImgUtil.cut(srcImage, new Rectangle(j * destWidth, i * destHeight, destWidth, destHeight));
                // 输出为文件
                // write(tag, FileUtil.file(descDir, "_r" + i + "_c" + j + ".jpg"));
                // 存储至缓存
                IMG_CACHE.put(uuid + "_" + i + "_" + j, tag);
            }
        }
    }
}
